﻿namespace ProblemsSet
{
    public class SmallRational
    {
        private int _nom = 0;
        private int _denom = 1;

        public int Nomirator
        {
            get
            {
                return _nom;
            }
        }

        public int Denomirator
        {
            get
            {
                return _denom;
            }
        }

        public SmallRational()
        {
        }

        public SmallRational(int nom)
        {
            _nom = nom;
        }

        public SmallRational(int nom, int denom)
        {
            _nom = nom;
            _denom = denom;
            Norm();
        }

        public SmallRational(SmallRational bi)
        {
            _nom = bi._nom;
            _denom = bi._denom;
        }

        public static implicit operator SmallRational(BigInteger value)
        {
            return (new SmallRational(value));
        }

        public static implicit operator SmallRational(int value)
        {
            return (new SmallRational(value));
        }

        public static implicit operator SmallRational(long value)
        {
            return (new SmallRational(value));
        }

        public static implicit operator SmallRational(ulong value)
        {
            return (new SmallRational(value));
        }

        public static SmallRational operator +(SmallRational bi1, SmallRational bi2)
        {
            SmallRational tmp = 0;
            tmp._nom = bi1._nom * bi2._denom + bi2._nom * bi1._denom;
            tmp._denom = bi1._denom * bi2._denom;
            tmp.Norm();
            return tmp;
        }

        public static SmallRational operator -(SmallRational bi1, SmallRational bi2)
        {
            SmallRational tmp = 0;
            tmp._nom = bi1._nom * bi2._denom - bi2._nom * bi1._denom;
            tmp._denom = bi1._denom * bi2._denom;
            tmp.Norm();
            return tmp;
        }

        public static SmallRational operator -(SmallRational bi1)
        {
            SmallRational tmp = 0;
            tmp._nom = -bi1._nom;
            tmp._denom = bi1._denom;
            tmp.Norm();
            return tmp;
        }

        public static SmallRational operator *(SmallRational bi1, SmallRational bi2)
        {
            SmallRational tmp = 0;
            tmp._nom = bi1._nom * bi2._nom;
            tmp._denom = bi1._denom * bi2._denom;
            tmp.Norm();
            return tmp;
        }

        public static SmallRational operator /(SmallRational bi1, SmallRational bi2)
        {
            SmallRational tmp = 0;
            tmp._nom = bi1._nom * bi2._denom;
            tmp._denom = bi1._denom * bi2._nom;
            tmp.Norm();
            return tmp;
        }

        public static bool operator ==(SmallRational bi1, SmallRational bi2)
        {
            return bi1.Equals(bi2);
        }

        public static bool operator !=(SmallRational bi1, SmallRational bi2)
        {
            return !(bi1.Equals(bi2));
        }

        public static bool operator >(SmallRational bi1, SmallRational bi2)
        {
            return bi1._nom * bi2._denom > bi2._nom * bi1._denom;
        }

        public static bool operator <(SmallRational bi1, SmallRational bi2)
        {
            return bi1._nom * bi2._denom < bi2._nom * bi1._denom; ;
        }

        public static bool operator >=(SmallRational bi1, SmallRational bi2)
        {
            return bi1._nom * bi2._denom >= bi2._nom * bi1._denom;
        }

        public static bool operator <=(SmallRational bi1, SmallRational bi2)
        {
            return bi1._nom * bi2._denom <= bi2._nom * bi1._denom; ;
        }

        public override string ToString()
        {
            if (_denom == 0)
                return "N/A";
            if (_denom == 1)
                return _nom.ToString();
            return string.Format("{0}/{1}", _nom, _denom);
        }

        public override bool Equals(object o)
        {
            var bi = (SmallRational)o;
            if (bi._nom * _denom == bi._denom * _nom)
                return true;

            return false;
        }

        public void Norm()
        {
            if (_denom == 0)
                return;
            var kf = 1;
            if (_nom < 0)
            {
                kf *= -1;
                _nom = -_nom;
            }
            if (_denom < 0)
            {
                kf *= -1;
                _denom = -_denom;
            }
            var tmp = (int)MathLogic.GetNOD(_nom, _denom);
            _nom /= tmp;
            _denom /= tmp;
            _nom *= kf;
        }

        public static SmallRational Norm(SmallRational value)
        {
            var tmp = value;
            tmp.Norm();
            return tmp;
        }

        public override int GetHashCode()
        {
            return this.ToString().GetHashCode();
        }

    }
}
